package com.cssnb.commons.utils.page;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class PagerTag extends SimpleTagSupport {

	private int linkCount = 10;
	private int curPage, totalPage;
	private String method = "GET";
	private String queryString = "";
	private String style = "";
	private String showBeginEnd = "true";
	private String showNumLink = "true";
	private String showPagerDetails = "false";
	private String showTurnPage = "false";
	private String pagerClass = "pagination";
	private String disabledClass = "disabled";
	private String activeClass = "active";
	private String curPageName = PageUtils.CURPAGE;

	@Override
	public void doTag() throws JspException, IOException{
		// getRequest
		HttpServletRequest request = ((HttpServletRequest) ((PageContext) getJspContext()).getRequest());
		if(request.getAttribute("page") != null){
			Map page = (Map) request.getAttribute("page");
			curPage = Integer.parseInt(page.get("curPage").toString());
			totalPage = Integer.parseInt(page.get("totalPage").toString());
			String url = page.get("pageUrl").toString(), attr = "";
			if(totalPage <= 0 || url == ""){ return; }
			// 获得参数字符串
			queryString = getQueryString(request);
			StringBuilder pagerStr = new StringBuilder(300);
			// 默认是GET方式请求
			if("POST".equalsIgnoreCase(method)){
				this.method = "POST";
				// 添加form表单,提交事件脚本
				pagerStr.append(getPostForm(getParameterMap(request), url));
			}else{
				this.method = "GET";
			}
			pagerStr.append(getScript(url));
			boolean isShowPagerDetails = !"false".equalsIgnoreCase(showPagerDetails);
			boolean isShowTurnPage = !"false".equalsIgnoreCase(showTurnPage);
			boolean isShowBeginEnd = !"false".equalsIgnoreCase(showBeginEnd);
			boolean isShowNumLink = !"false".equalsIgnoreCase(showNumLink);
			pagerStr.append("<div id=\"pager\" class=\"clearfix " + this.pagerClass + "\"" + (this.style == "" ? "" : " style=\"" + this.style + "\"") + ">\r\n");
			if(isShowPagerDetails || isShowTurnPage){
				// 分页详细信息
				pagerStr.append("<div class=\"turnPager\" style=\"margin-right:5px;height:34px;width:auto;display:inline-block;\">");
				if(isShowPagerDetails){
					pagerStr.append("<em style=\"font-style:normal;float:left;height:32px;line-height:32px;\"> 共 " + page.get("totalResult") + " 条 每页 " + page.get("pageSize") + " 条 共 " + totalPage + " 页 第 " + curPage + " 页</em>");
				}
				// 跳转页面
				if(isShowTurnPage){
					pagerStr.append("<em style=\"font-style:normal;float:left;height:32px;line-height:32px;\"> 到第</em>\r\n");
					pagerStr.append("<input type=\"text\" id=\"k_txtCurPage\" class=\"txtCurPage\" style=\"width:24px;float:left;\">\r\n");
					pagerStr.append("<button class=\"btn\" onclick=\"turnPager(document.getElementById('k_txtCurPage').value);\" style=\"float:left;\">go</button>\r\n");
				}
				pagerStr.append("</div>\r\n");
			}
			pagerStr.append("<ul>");
			// 首页\上一页
			if(curPage <= 1){
				attr = " class=\"" + this.disabledClass + "\" disabled=\"disabled\" hideFocus=\"true\"";
				if(isShowBeginEnd) pagerStr.append("<li" + attr + "><a href=\"javascript:void(0);\"" + ">首页</a></li>\r\n");
				pagerStr.append("<li" + attr + "><a href=\"javascript:void(0);\"" + attr + ">上一页</a></li>\r\n");
			}else{
				attr = " class=\"prev\" hideFocus=\"true\"";
				if(isShowBeginEnd) pagerStr.append("<li " + attr + "><a" + getHref(url, 1) + ">首页</a></li>\r\n");
				pagerStr.append("<li" + attr + "><a" + getHref(url, (curPage - 1)) + attr + ">上一页</a></li>\r\n");
			}
			// 数字链接
			if(isShowNumLink){
				int first = 1, last = totalPage < linkCount ? totalPage : linkCount;
				if(curPage > linkCount / 2 + 1){
					if(totalPage - curPage < linkCount && curPage + linkCount / 2 > totalPage){
						first = totalPage - linkCount + 1;
						first = first < 1 ? 1 : first;
						last = totalPage;
					}else{
						first = curPage - linkCount / 2;
						last = first + linkCount - 1;
					}
				}
				for(int i = first; i <= last; i++){
					attr = i == curPage ? " class=\"" + this.activeClass + " num\" hideFocus=\"true\"" : " class=\"num\" hideFocus=\"true\"";
					// sb.append("<a" + getHref(url, i) + attr + ">" + i + "</a>\r\n");
					pagerStr.append("<li" + attr + "><a" + getHref(url, i) + ">" + i + "</a></li>\r\n");
					// sb.append("<span class=\"text\">…</span>");
				}
			}
			// 下一页\末页
			if(curPage >= totalPage){
				attr = " class=\"" + this.disabledClass + "\" disabled=\"disabled\" hideFocus=\"true\"";
				pagerStr.append("<li" + attr + "><a href=\"javascript:void(0);\"" + ">下一页</a></li>\r\n");
				if(isShowBeginEnd) pagerStr.append("<li" + attr + "><a href=\"javascript:void(0);\">末页</a></li>\r\n");
			}else{
				attr = " class=\"next\" hideFocus=\"true\"";
				pagerStr.append("<li" + attr + "><a" + getHref(url, (curPage + 1)) + ">下一页</a></li>\r\n");
				if(isShowBeginEnd) pagerStr.append("<li" + attr + "><a" + getHref(url, totalPage) + ">末页</a></li>\r\n");
			}
			pagerStr.append("</ul>");
			pagerStr.append("</div>\r\n");
			getJspContext().getOut().print(pagerStr);
		}
	}
	/**
	 * 返回超链接字符串
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:19:01
	 */
	private String getHref(String url, int curPage){
		if("POST".equals(method)){
			return " href=\"javascript:void(0);\" onclick=\"turnPager(" + curPage + "); return false;\"";
		}else{
			return " href=\"" + url + this.queryString + curPage + "\"";
		}
	}
	/**
	 * POST表单提交
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:16:27
	 */
	private String getPostForm(Map pMap, String action){
		StringBuilder sb = new StringBuilder();
		sb.append("<form style=\"display:none;\" id=\"pagerForm\" action=\"" + action + "\" method=\"post\">\r\n");
		Object[] keys = pMap.keySet().toArray();
		for(int i = 0; i < pMap.size(); i++){
			if(this.curPageName.equals(keys[i])){
				continue;
			}
			sb.append("	<input type=\"hidden\" name=\"" + keys[i] + "\" value=\"" + pMap.get(keys[i]) + "\">\r\n");
		}
		sb.append("<input type=\"hidden\" id=\"curPage\" name=\"" + this.curPageName + "\" value=\"\">\r\n");
		sb.append("</form>\r\n");
		return sb.toString();
	}
	/**
	 * 插入页面跳转脚本
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:16:34
	 */
	private String getScript(String url){
		return "<script>function turnPager(curPage){var win = parent != window ? parent : window;if(!curPage || !/^[0-9]+$/.test(curPage) || curPage < 1 || curPage > " + totalPage + "){" + "win.alert(\"您输入的页面不正确或存在!\", \"\", function(){document.getElementById('k_txtCurPage').focus();});return;}else if(curPage != " + curPage + "){"
				+ ("POST".equals(method) ? "document.getElementById('curPage').value = curPage;document.getElementById('pagerForm').submit();" : "location.href = \"" + url + this.queryString + "\" + curPage;") + "}}</script>";
	}
	/**
	 * 获取页面参数
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:16:40
	 */
	private Map getParameterMap(HttpServletRequest request){
		Map parameterMap = request.getParameterMap();
		String method = request.getMethod();
		Map map = new HashMap();
		Object temp = null;
		Object[] tempKey = parameterMap.keySet().toArray();
		for(int i = 0; i < tempKey.length; i++){
			temp = ((Object[]) parameterMap.get(tempKey[i]))[0];
			if(temp != null && !"".equals(tempKey) && "GET".equals(method)){
				try{
					temp = new String(temp.toString().getBytes("ISO-8859-1"), "GBK");
				}catch(UnsupportedEncodingException e){
					e.printStackTrace();
				}
			}
			map.put(tempKey[i], temp);
		}
		return map;
	}
	/**
	 * 获取分页参数字符串
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:16:56
	 */
	private String getQueryString(HttpServletRequest request){
		String queryString = "";
		Map parameterMap = request.getParameterMap();
		String method = request.getMethod();
		Object temp = null;
		Object[] tempKey = parameterMap.keySet().toArray();
		for(int i = 0; i < tempKey.length; i++){
			temp = ((Object[]) parameterMap.get(tempKey[i]))[0];
			if(temp != null && !"".equals(tempKey) && "GET".equals(method)){
				try{
					temp = new String(temp.toString().getBytes("ISO-8859-1"), "GBK");
				}catch(UnsupportedEncodingException e){
					e.printStackTrace();
				}
			}
			// 去掉当前页，拼接到最后面
			if(this.curPageName.equals(tempKey[i])){
				continue;
			}
			queryString += (queryString == "" ? "?" : "&") + tempKey[i] + "=" + temp;
		}
		if(queryString == ""){
			queryString += "?" + this.curPageName + "=";
		}else{
			queryString += "&" + this.curPageName + "=";
		}
		return queryString;
	}
	/**
	 * 设置css样式
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 下午3:58:10
	 */
	public void setStyle(String style){
		this.style = style;
	}
	/**
	 * 设置链接数量
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:18:40
	 */
	public void setLinkCount(int count){
		count = count < 1 ? 10 : count;
		this.linkCount = count;
	}
	/**
	 * 设置请求方式(POST,GET)
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:18:28
	 */
	public void setMethod(String method){
		this.method = method;
	}
	/**
	 * 显示起始链接
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:18:10
	 */
	public void setShowBeginEnd(String showBeginEnd){
		this.showBeginEnd = showBeginEnd;
	}
	/**
	 * 显示数字链接
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:17:56
	 */
	public void setShowNumLink(String showNumLink){
		this.showNumLink = showNumLink;
	}
	/**
	 * 显示分页详细信息
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:17:31
	 */
	public void setShowPagerDetails(String showPagerDetails){
		this.showPagerDetails = showPagerDetails;
	}
	/**
	 * 显示跳转页
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:17:40
	 */
	public void setShowTurnPage(String showTurnPage){
		this.showTurnPage = showTurnPage;
	}
	/**
	 * 分页样式
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:27:20
	 */
	public void setPagerClass(String pagerClass){
		this.pagerClass = pagerClass;
	}
	/**
	 * 设置禁用样式名称
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:48:50
	 */
	public void setDisabledClass(String disabledClass){
		this.disabledClass = disabledClass;
	}
	/**
	 * 设置当前页样式名称
	 * @Author: 卜繁晟
	 * @Created Date: 2013-4-24 上午9:49:02
	 */
	public void setActiveClass(String activeClass){
		this.activeClass = activeClass;
	}
}